package org.urchr.beorganized.api.impl;
/*
 * 
 * */
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.io.FilenameUtils;
import org.urchr.beorganized.api.base.Log;
import org.urchr.beorganized.api.base.PrivateBaseAPIServlet;
import org.urchr.beorganized.dao.NotesDAO;
import org.urchr.beorganized.dao.UsersDAO;
import org.urchr.beorganized.dao.XMLDocumentBuilder;
import org.urchr.beorganized.dao.errors.DBErrorException;
import org.urchr.beorganized.dao.errors.GeneralException;
import org.urchr.beorganized.dao.errors.InvalidFileException;
import org.urchr.beorganized.dao.errors.NoPermissionException;
import org.urchr.beorganized.dao.tables.Note;
import org.urchr.beorganized.dao.tables.User;

public class SaveNote extends PrivateBaseAPIServlet {

	static Map<String, Object> results = new HashMap<String, Object>();
	
	public SaveNote() {
		skipBody = true;
	}
	
	@Override
	protected void doProcessPrivate() throws GeneralException {
//		System.out.println("id = "+getParameter("id")+", new: "+getParameter("newNote")+
//				", rnd = "+getParameter("rnd")+", c = "+getParameter("completed"));
		if(getParameter("rnd")==null || "".equals(getParameter("rnd")))
			throw new NoPermissionException();
		try {
			boolean newNote = "true".equals(getParameter("newNote"));
			Note note = new Note();
//			if(newNote)
//				note.setShareCode(Note.genRandomString());
			note.setId(NotesDAO.safeInt(getParameter("id"), 0));
			note.setType(NotesDAO.safeInt(getParameter("type"), 0));
			note.setCustomIcon(NotesDAO.safeInt(getParameter("customIcon"), note.getType()));
			if("true".equals(getParameter("forceutf"))){
				try {
					note.setName(new String(getParameter("name").getBytes("latin1"), "utf-8"));					
				} catch (Exception e) {}
			}else
				note.setName(getParameter("name"));				
			note.setCompleted("true".equals(getParameter("completed"))?1:0);
			
			note.setUrl(getParameter("url"));
			note.setRecurrence(getParameter("recurrence"));
			note.setPriority(NotesDAO.safeInt(getParameter("priority"), 2));
			note.setData(getParameter("textContent")!=null?getParameter("textContent").getBytes("utf-8"):null);
			FileItem item = getFile("file");
			if((note.getType()==Note.TYPE_IMAGE || note.getType()==Note.TYPE_FILE) 
					&& item!=null && item.getSize()>0){
				if(item.getSize()>NotesDAO.FILES_MAX_SIZE)
					throw new InvalidFileException();
				String fileName = item.getName();
			    if (fileName != null) {
			        fileName = FilenameUtils.getName(fileName);
			    }
				note.setFileName(fileName);
				note.setFileSize((int)item.getSize());
				note.setContentType(item.getContentType());
				note.setData(item.get());
			}
			User user = UsersDAO.getUser(userID);
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
			try {
				note.setStartDate(format.parse(getParameter("startDate")));
				if(note.getType()==Note.TYPE_EVENT){
					Calendar c = Calendar.getInstance();
					c.setTime(note.getStartDate());
					c.add(c.MINUTE, -user.getMinuteOffsetByDate(note.getStartDate()));
					note.setStartDate(c.getTime());
				}
			} catch (Exception e2) {
			}
			try {
				note.setEndDate(format.parse(getParameter("endDate")));
				if(note.getType()==Note.TYPE_EVENT){
					Calendar c = Calendar.getInstance();
					c.setTime(note.getEndDate());
					c.add(Calendar.MINUTE, -user.getMinuteOffsetByDate(note.getEndDate()));
					note.setEndDate(c.getTime());
				}
			} catch (Exception e2) {
			}
			note.setTagsString(getParameter("tags"));
			if("true".equals(getParameter("quickadd"))){
				parseQuickAdd(note, user.getDateFormat(), Note.getUserNow(user));
			}
			int result = NotesDAO.saveNote(servletContext, note, newNote, 
					note.getTagsString(), !"false".equals("savetags"), userID, false).getId();
//			Log.debug(this, "Put result: "+getParameter("rnd"));
			results.put(getParameter("rnd"), new Integer(result));
			XMLDocumentBuilder doc = new XMLDocumentBuilder();
			doc.getRootElement("note").setAttribute("id", ""+result);
			sendNode(doc.getRootElement());
//			throw new NoPermissionException();			
		} catch (Exception e) {
			if(e instanceof GeneralException){
				results.put(getParameter("rnd"), e);
			}else{
				e = new DBErrorException();
				results.put(getParameter("rnd"), e);
			}
			throw (GeneralException)e;
		}
//		if(xmlObject!=null){
//			boolean newNote = "true".equals(request.getParameter("new"));
//			Note note = NotesDAO.nodeToNote(xmlObject, userID);
//			int noteID = NotesDAO.saveNote(note.getId(), note, newNote, xmlObject.getAttribute("tags"), 
//					"true".equals(request.getParameter("savetags")), userID);
//			XMLDocumentBuilder doc = new XMLDocumentBuilder();
//			sendNode(NotesDAO.fullNoteToElement(doc, doc.getRootElement("note"), noteID, userID, true));			
//		}
	}
	
	private void parseQuickAdd(Note note, String dateFormat, Calendar today){
		String string = note.getName();
		String taskName = "";
		boolean recurred = false;
		int recType = -1;
		int recDays = 0;
		int priority = 2;
		String tags = "";
		String recurrence = "";
		Date dueDate = null;
		
		boolean ok = true;
		SimpleDateFormat format = new SimpleDateFormat(dateFormat);
		while(ok){
			String word = nextWord(string);
			if(word.equals("")){
				break;
			}
			boolean d = word.equalsIgnoreCase("day") || word.equalsIgnoreCase("days");
			boolean w = word.equalsIgnoreCase("week") || word.equalsIgnoreCase("weeks");
			boolean m = word.equalsIgnoreCase("month") || word.equalsIgnoreCase("months");
			boolean y = word.equalsIgnoreCase("year") || word.equalsIgnoreCase("years");
			if(word.equalsIgnoreCase("daily")){
				d = true;
				recDays = 1;
			}
			if(word.equalsIgnoreCase("weekly")){
				w = true;
				recDays = 1;
			}
			if(word.equalsIgnoreCase("monthly")){
				m = true;
				recDays = 1;
			}
			if(word.equalsIgnoreCase("yearly") || word.equalsIgnoreCase("annually")){
				y = true;
				recDays = 1;
			}
			if(d || w || m || y){
				String days = "";
				if(recDays==0){
					string = skipWord(string);
					days = nextWord(string);
					try {
						recDays = Integer.parseInt(days);
					} catch (Exception e) {
						
					}
					if(recDays==0){
						string += word;
						break;
					}
				}
				string = skipWord(string);
				String nextToken = nextWord(string);
				if(nextToken.equalsIgnoreCase("every") || nextToken.equalsIgnoreCase("ev")){
					string = skipWord(string);
					nextToken = nextWord(string);
					recType = 0;//Repeat
				}
				if(nextToken.equalsIgnoreCase("after")){
					recType = 1;//After
				}
				
				if(nextToken.equalsIgnoreCase("repeat")){
					recType = 0;//After
				}
				if(recType==-1){
					string += days+" "+word;
					break;
				}
				recurred = true;
				recurrence  = (recType==0?"repeat_":"after_")+recDays+"_";
				if(d)
					recurrence += "days";
				if(w)
					recurrence += "weeks";
				if(m)
					recurrence += "months";
				if(y)
					recurrence += "years";
				string = skipWord(string);
				continue;
			}
			if(word.equalsIgnoreCase("repeat")){
				string = skipWord(string);
				continue;				
			}
			if(word.startsWith("@") && word.length()>1){
				if(!tags.equals(""))
					tags += ",";
				tags += word.substring(1).toLowerCase();
				string = skipWord(string);
				continue;				
			}
			if(word.startsWith("!p")){
				try {
					priority = Integer.parseInt(word.substring(2));
				} catch (Exception e) {
				}
				string = skipWord(string);
				continue;				
			}
			if(word.equalsIgnoreCase("tod") || word.equalsIgnoreCase("today")){
				dueDate = today.getTime();
				string = skipWord(string);
				continue;				
			}
			if(word.equalsIgnoreCase("tom") || word.equalsIgnoreCase("tomorrow")){
				today.add(Calendar.DAY_OF_YEAR, 1);
				dueDate = today.getTime();
				string = skipWord(string);
				continue;				
			}
			try {
				dueDate = format.parse(word);
				if(dueDate!=null){
					string = skipWord(string);
					continue;					
				}
			} catch (Exception e) {
			}
			break;
		}
		taskName = string.trim();
		//Fill note
		note.setName(taskName);
		note.setTagsString(tags);
		note.setPriority(priority);
		if(dueDate!=null){
			Calendar c = Calendar.getInstance();
			c.setTime(dueDate);
			c.set(Calendar.HOUR_OF_DAY, 12);
			c.set(Calendar.MINUTE, 0);
			note.setStartDate(c.getTime());
		}
		if(recurred)
			note.setRecurrence(recurrence);
	}
	
	private String nextWord(String string){
		String s = string.trim();
		if(s.lastIndexOf(" ")==-1)
			return string;
		return s.substring(s.lastIndexOf(" ")+1);
	}

	private String skipWord(String string){
		String s = string.trim();
		if(s.lastIndexOf(" ")==-1)
			return "";
		return s.substring(0, s.lastIndexOf(" ")).trim();
	}
}
